//
// Created by Gorun on 2022/5/2.
//

#ifndef LOXPP_TOKEN_H
#define LOXPP_TOKEN_H

#include <any>
#include <string>
#include <utility>
#include "TokenType.h"

using namespace std;

class Token {
public:
    const TokenType type;
    const string lexeme;
    const any literal;
    const int line;
    const int column;

    Token(TokenType type, string lexeme, any literal, int line, int column)
        : type{type}, lexeme{move(lexeme)},
          literal{literal}, line{line}, column{column}
    {}

    //There's no need to represent the Token into
    //seperated class, Lox is a dynamic type language.
    //Literal text can be got from lexeme, of course.
    string toString() const {
        string literal_text;

        switch (type) {
            case IDENTIFIER:
                literal_text=lexeme;
                break;
            case STRING:
                literal_text=any_cast<string>(literal);
                break;
            case NUMBER:
                literal_text=to_string(any_cast<double>(literal));
                break;
            case TRUE:
                literal_text="true";
                break;
            case FALSE:
                literal_text="false";
                break;
            default:
                literal_text="nil";
        }

        return ::toString(type)+" "+lexeme+" "+literal_text;
    }
};

#endif //LOXPP_TOKEN_H
